package org.example.service.project.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.example.mapper.ProjectInfoMapper;
import org.example.model.common.AppHttpCodeEnum;
import org.example.model.common.PageResponseDto;
import org.example.model.common.ResponseResult;
import org.example.model.project.dtos.ProjectInfoDto;
import org.example.model.project.entities.ProjectInfo;
import org.example.model.project.statement.ProjectTimeSpent;
import org.example.model.project.vos.AddProjectInfoVo;
import org.example.model.project.vos.SearchProjectInfoVo;
import org.example.model.user.dtos.UserIdentityDto;
import org.example.model.workItem.dtos.WorkItemDto;
import org.example.model.workItem.vos.SearchWorkItemVo;
import org.example.service.project.ProjectInfoService;
import org.example.service.workItem.WorkItemService;
import org.example.utils.UserIdThreadLocalUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 项目信息服务层实现
 */
@Service
@Transactional
@Slf4j
public class ProjectInfoServiceImpl extends ServiceImpl<ProjectInfoMapper, ProjectInfo> implements ProjectInfoService {

    @Autowired
    private ProjectInfoMapper projectInfoMapper;

    @Autowired
    private WorkItemService workItemService;

    /**
     * 添加一则项目信息记录
     * @param addProjectInfoVo 需要修改的项目信息
     */
    @Override
    public ResponseResult<Boolean> InsertProjectInfo(AddProjectInfoVo addProjectInfoVo) {
        ResponseResult<Boolean> result = new ResponseResult<>();
        // 参数审查
        if (addProjectInfoVo == null) {
            // 缺少参数
            result.error(AppHttpCodeEnum.PARAM_REQUIRE.getCode(), AppHttpCodeEnum.PARAM_REQUIRE.getErrorMessage());
            return result;
        }
        ProjectInfo projectInfo = new ProjectInfo();
        BeanUtils.copyProperties(addProjectInfoVo, projectInfo);
        this.HandleModifyProjectInfo(projectInfo);
        Boolean flag = projectInfoMapper.insert(projectInfo) > 0;
        result.ok(AppHttpCodeEnum.SUCCESS.getCode(), flag, AppHttpCodeEnum.SUCCESS.getErrorMessage());
        return result;
    }

    /**
     * 添加或修改日报信息统一操作
     */
    private void HandleModifyProjectInfo (ProjectInfo projectInfo) {
        // 获取进程中的用户数据
        UserIdentityDto userIdentityDto = UserIdThreadLocalUtils.getUser();
        if (projectInfo.getId() == 0) {
            projectInfo.setCreateUserId(userIdentityDto.getId());
            projectInfo.setCreateTime(LocalDateTime.now());
            projectInfo.setIsDeleted(false);
        }
        projectInfo.setUpdateUserId(userIdentityDto.getId());
        projectInfo.setUpdateTime(LocalDateTime.now());
    }

    /**
     * 根据id修改一则项目信息记录
     * @param addProjectInfoVo 需要修改的项目信息
     */
    @Override
    public ResponseResult<Boolean> UpdateProjectInfoById(AddProjectInfoVo addProjectInfoVo) {
        ResponseResult<Boolean> result = new ResponseResult<>();
        // 参数审查
        if (addProjectInfoVo == null || addProjectInfoVo.getId() <= 0) {
            // 缺少参数 项目信息id
            result.error(AppHttpCodeEnum.PARAM_REQUIRE.getCode(), AppHttpCodeEnum.PARAM_REQUIRE.getErrorMessage());
            return result;
        }
        ProjectInfo projectInfo = projectInfoMapper.selectById(addProjectInfoVo.getId());
        BeanUtils.copyProperties(addProjectInfoVo, projectInfo);
        this.HandleModifyProjectInfo(projectInfo);
        Boolean flag = projectInfoMapper.updateById(projectInfo) > 0;
        result.ok(AppHttpCodeEnum.SUCCESS.getCode(), flag, AppHttpCodeEnum.SUCCESS.getErrorMessage());
        return result;
    }

    /**
     * 根据id删除一则项目信息记录
     * @param id 项目id
     */
    @Override
    public ResponseResult<Boolean> DeleteProjectInfoById(int id) {
        ResponseResult<Boolean> result = new ResponseResult<>();
        // 参数审查
        if (id <= 0) {
            // 缺少参数 项目信息id
            result.error(AppHttpCodeEnum.PARAM_REQUIRE.getCode(), AppHttpCodeEnum.PARAM_REQUIRE.getErrorMessage());
            return result;
        }
        ProjectInfo projectInfo = projectInfoMapper.selectById(id);
        projectInfo.setIsDeleted(true);
        this.HandleModifyProjectInfo(projectInfo);
        Boolean flag = projectInfoMapper.updateById(projectInfo) > 0;
        result.ok(AppHttpCodeEnum.SUCCESS.getCode(), flag, AppHttpCodeEnum.SUCCESS.getErrorMessage());
        return result;
    }

    /**
     * 根据条件分页查询项目信息
     * @param searchProjectInfoVo 查询条件
     */
    @Override
    public ResponseResult<PageResponseDto<List<ProjectInfoDto>>> SelectProjectInfoListByConditions(SearchProjectInfoVo searchProjectInfoVo) {
        ResponseResult<PageResponseDto<List<ProjectInfoDto>>> result = new ResponseResult<>();
        // 参数审查
        if (searchProjectInfoVo == null) {
            // 缺少参数 项目信息id
            result.error(AppHttpCodeEnum.PARAM_REQUIRE.getCode(), AppHttpCodeEnum.PARAM_REQUIRE.getErrorMessage());
            return result;
        }
        // 查询条件
        LambdaQueryWrapper<ProjectInfo> projectQuery = new LambdaQueryWrapper<>();
        projectQuery.eq(ProjectInfo::getIsDeleted, false);
        // 创建时间倒序排
        projectQuery.orderByDesc(ProjectInfo::getCreateTime);
        // 项目名模糊查询，项目类型模糊查询
        projectQuery.like(StringUtils.isNotBlank(searchProjectInfoVo.getProjectName()), ProjectInfo::getProjectName, searchProjectInfoVo.getProjectName())
                .eq(searchProjectInfoVo.getProjectType() != null, ProjectInfo::getProjectType,  searchProjectInfoVo.getProjectType());
        // 分页处理数据
        IPage<ProjectInfo> page = new Page<>(searchProjectInfoVo.getPageIndex(), searchProjectInfoVo.getPageSize());
        IPage<ProjectInfo> projectListByPage = projectInfoMapper.selectPage(page, projectQuery);
        // 应返回数据
        PageResponseDto<List<ProjectInfoDto>> pageResponseDto = new PageResponseDto<>();
        pageResponseDto.setSize(projectInfoMapper.selectCount(projectQuery).intValue());
        List<ProjectInfo> projectListRecords = projectListByPage.getRecords();
        List<ProjectInfoDto> projectInfoDtos = new ArrayList<>();
        ProjectInfoDto projectInfoDto = null;
        for (ProjectInfo projectInfo : projectListRecords) {
            projectInfoDto = new ProjectInfoDto();
            BeanUtils.copyProperties(projectInfo, projectInfoDto);
            projectInfoDtos.add(projectInfoDto);
        }
        pageResponseDto.setData(projectInfoDtos);
        result.ok(AppHttpCodeEnum.SUCCESS.getCode(), pageResponseDto, AppHttpCodeEnum.SUCCESS.getErrorMessage());
        return result;
    }

    /**
     * 根据项目id获取项目名
     */
    @Override
    public String GetProjectNameById(int id) {
        return projectInfoMapper.selectById(id).getProjectName();
    }

    /**
     * 获取除公司开发类别以外的项目总用时统计
     */
    @Override
    public ResponseResult<List<ProjectTimeSpent>> GetAllProjectExCompanyTimeSpent() {
        LambdaQueryWrapper<ProjectInfo> projectQuery = new LambdaQueryWrapper<>();
        projectQuery.eq(ProjectInfo::getIsDeleted, false)
                .ne(ProjectInfo::getProjectType, 0);
        List<ProjectInfo> projectInfoList = projectInfoMapper.selectList(projectQuery);
        List<ProjectTimeSpent> projectTimeSpentStatisticsList = new ArrayList<>();
        ProjectTimeSpent projectTimeSpent = null;
        for (ProjectInfo projectInfo : projectInfoList) {
            projectTimeSpent = new ProjectTimeSpent();
            projectTimeSpent.setProjectName(projectInfo.getProjectName());
            double timeSpent = workItemService.GetProjectTimeSpentByProjectId(projectInfo.getId());
            projectTimeSpent.setTimeSpent(timeSpent);
            projectTimeSpentStatisticsList.add(projectTimeSpent);
        }
        ResponseResult<List<ProjectTimeSpent>> result= new ResponseResult<>();
        result.ok(AppHttpCodeEnum.SUCCESS.getCode(), projectTimeSpentStatisticsList, AppHttpCodeEnum.SUCCESS.getErrorMessage());
        return result;
    }
}
